package com.xk.config;

import com.cms.common.core.exception.ServiceException;
import com.xk.constant.DictTypeConstant;
import com.xk.service.DictDataService;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Map;

@Data
@Component
@RefreshScope
@RequiredArgsConstructor
@ConfigurationProperties(prefix = "stuent.paper")
public class ExamNacosConfig {

    /**
     * 字典数据服务
     */
    private final DictDataService  dictDataService;


    /**
     * 考试时间时长，单位：分钟
     */
    private Long duration;

    /**
     * 每个题型选出多少题，key(题型编号1-3):数量
     */
    private Map<Long, Long> typeNums;

    /**
     * 考试总分
     */
    private Long totalPoints;

    /**
     * 合格线，百分制
     */
    private Long passTotal;

    /**
     * 每个题型的分数占比，keyuestaionType(题型编号1-3):分数占比(百分制 40等于 40%)
     */
    private Map<Long, Long> config;

    /**
     * 校验配置项是否有效
     */
    @PostConstruct
    public void validateConfig() {

        // 校验配置项是否为空
        if(duration == null){
            throw new ServiceException("配置项:stuent.paper.duration,考试时长不能为空，请检查 Nacos 配置，请联系管理员",500);
        }
        if(typeNums == null){
            throw new ServiceException("配置项:stuent.paper.typeNums,题型数量不能为空，请检查 Nacos 配置，请联系管理员",500);
        }
        if(totalPoints == null){
            throw new ServiceException("配置项:stuent.paper.totalPoints,考试总分不能为空，请检查 Nacos 配置，请联系管理员",500);
        }
        if(passTotal == null){
            throw new ServiceException("配置项:stuent.paper.passTotal,合格线不能为空，请检查 Nacos 配置，请联系管理员",500);
        }
        if(config == null){
            throw new ServiceException("配置项:stuent.paper.config,题型分数占比不能为空，请检查 Nacos 配置，请联系管理员",500);
        }

        // 集合元素不能为空
        if (typeNums.isEmpty()) {
            throw new ServiceException("配置项:stuent.paper.typeNums,题型数量不能为空，请检查 Nacos 配置，请联系管理员",500);
        }
        if (config.isEmpty()) {
            throw new ServiceException("配置项:stuent.paper.config,题型分数占比不能为空，请检查 Nacos 配置，请联系管理员",500);
        }


        // 校验配置项是否有效
        if (duration <= 0) {
            throw new ServiceException("配置项:stuent.paper.duration,考试时长必须为正整数，请检查 Nacos 配置，请联系管理员",500);
        }
        if (totalPoints <= 0) {
            throw new ServiceException("配置项:stuent.paper.totalPoints,考试总分必须为正整数，请检查 Nacos 配置，请联系管理员",500);
        }
        if (passTotal <= 0 || passTotal > 100) {
            throw new ServiceException("配置项:stuent.paper.passTotal,合格线必须为 1 到 100 的整数，请检查 Nacos 配置，请联系管理员",500);
        }

        // 校验分数占比总和是否为 100
        long totalPercentage = config.values().stream().mapToLong(Long::intValue).sum();
        if (totalPercentage != 100) {
            throw new ServiceException("配置项:stuent.paper.config,考试题型分数占比总和必须为 100，请检查各个题型的分数占比，请联系管理员",500);
        }
        // 校验 typeNums 元素是否为正整数
        typeNums.values().forEach(num -> {
            if (num <= 0) {
                throw new ServiceException("配置项:stuent.paper.typeNums,题型数量必须为正整数，请检查 Nacos 配置，请联系管理员",500);
                }
            });
        // 校验 typeNums 和 config 的键集合是否一致
        if (!typeNums.keySet().equals(config.keySet())) {
            throw new ServiceException("题型数量和分数占比的题型编号不一致，请检查配置项 stuent.paper.typeNums 和 stuent.paper.config，请联系管理员",500);
        }
        //获取的typeNums的key值
        for (Long type : typeNums.keySet()) {
            //数据库中是否存在该题型
            if(!dictDataService.checkDictData(type, DictTypeConstant.EXAM_QUESTION_TYPE)){
                throw new ServiceException("题型编号: " + type + " 不存在，请检查配置项配置项:stuent.paper.typeNums，请联系管理员",500);
            }
        }
        //获取的config的key值
        for (Long type : config.keySet()) {
            //数据库中是否存在该题型
            if(!dictDataService.checkDictData(type, DictTypeConstant.EXAM_QUESTION_TYPE)){
                throw new ServiceException("题型编号: " + type + " 不存在，请检查配置项配置项:stuent.paper.config，请联系管理员",500);
            }
        }
    }
}
